package com.forum.core.service;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import org.hibernate.Query;
import org.hibernate.Session;

import com.forum.core.dao.Page;
import com.forum.core.dao.PropertyFilter;

/**
 * @author zhangwei
 * @version2.0 定义service层公用接口信息
 */
public interface IBaseService {

    public Session getSession();

    /**
     * 保存新增对象.
     */
    public void saveOrUpdate(final Object entity);

    /**
     * 保存新增对象.
     */
    public void save(final Object entity);

    /**
     * 修改的对象.
     */
    public void update(final Object entity);

    /**
     * 删除对象.
     */
    public void delete(final Object entity);

    /**
     * 按id删除对象.
     */
    public void delete(Class clazz, final Serializable id);

    /**
     * 按id获取对象.get方法
     */
    public <T> T get(Class<T> clazz, final Serializable id);

    /**
     * 根据ID获取对象load方法
     *
     * @param id
     * @return
     */
    public <T> T load(Class<T> clazz, final Serializable id);

    /**
     * 获取所有数据
     */
    public List getAll(Class clazz);

    /**
     * 按属性查找对象列表,匹配方式为相等.
     */
    public List findBy(final String propertyName, final Object value);

    /**
     * 按HQL查询对象列表.
     *
     * @param values 数量可变的参数,按顺序绑定.
     */
    public List find(final String hql, final Object... values);

    /**
     * 按HQL查询对象列表.
     *
     * @param value 数量可变的参数
     */
    public List find(final String hql, final Object value);

    /**
     * 按HQL查询对象列表.
     *
     * @param values 命名参数,按名称绑定.
     */
    public List find(final String hql, final Map<String, Object> values);

    /**
     * 按HQL查询唯一对象.
     *
     * @param values 数量可变的参数,按顺序绑定.
     */
    public <T> T findUnique(final String hql, final Object... values);

    /**
     * 按HQL查询唯一对象.
     *
     * @param values 命名参数,按名称绑定.
     */
    public <T> T findUnique(final String hql, final Map<String, Object> values);

    /**
     * 执行HQL进行批量修改/删除操作.
     */
    public int batchExecute(final String hql, final Object... values);

    /**
     * 执行HQL进行批量修改/删除操作.
     *
     * @return 更新记录数.
     */
    public int batchExecute(final String hql, final Map<String, ?> values);

    /**
     * 根据查询HQL与参数列表创建Query对象.
     * <p/>
     * 本类封装的find()函数全部默认返回对象类型为T,当不为T时使用本函数.
     *
     * @param values 数量可变的参数,按顺序绑定.
     */
    public Query createQuery(final String queryString, final Object... values);

    /**
     * 根据查询HQL与参数列表创建Query对象.
     *
     * @param values 命名参数,按名称绑定.
     */
    public Query createQuery(final String queryString, final Map<String, ?> values);

    /**
     * 根据查询SQL与参数列表创建Query对象.
     * <p/>
     * 本类封装的find()函数全部默认返回对象类型为T,当不为T时使用本函数.
     *
     * @param values 数量可变的参数,按顺序绑定.
     */
    public Query createSQLQuery(final String queryString, final Object... values);

    /**
     * 根据查询SQL与参数列表创建Query对象.
     *
     * @param values 命名参数,按名称绑定.
     */
    public Query createSQLQuery(final String queryString, final Map<String, Object> values);

    /**
     * 初始化对象.
     * 使用load()方法得到的仅是对象Proxy后, 在传到View层前需要进行初始化.
     * initObject(user) ,初始化User的直接属性，但不会初始化延迟加载的关联集合和属性.
     * initObject(user.getRoles())，初始化User的直接属性和关联集合.
     * initObject(user.getDescription())，初始化User的直接属性和延迟加载的Description属性.
     */
    public void initObject(Object object);

    /**
     * 批量初始化对象.
     *
     * @see #initObject(Object)
     */
    public void initEntity(List entityList);

    /**
     * 通过Set将不唯一的对象列表唯一化.
     * 主要用于HQL/Criteria预加载关联集合形成重复记录,又不方便使用distinct查询语句时.
     */
    public List distinct(List list);

    public Query distinct(Query query);

    /**
     * 取得对象的主键名.
     */
    public String getIdName(Class clazz);

    /**
     * 执行hql语句。
     */
    public void executeHQL(String hql);

    public void executeHQL(String hql, final Object... values);

    /**
     * 执行hql语句。
     */
    public void executeDelete(String hql);

    /**
     * 执行sql语句。
     *
     * @throws java.sql.SQLException
     * @throws org.hibernate.HibernateException
     *
     */
    @SuppressWarnings("deprecation")
    public void executeSQL(String sql);

    /**
     * 效验数据库是否存在该记录
     */
    public boolean isTrueHQL(String hql);

    /**
     * @param entity
     * @param fields
     * @author zhangjj
     * @Date 2010-08-25 10:19:24
     * @description 有时候我们只想更新表的部分字段，可是hibernate不支持部分字段的更新，所以这里写了一个这样的方法，根据主键更新部分字段，多个字段通过“,”分割。
     */
    public void update(final Object entity, String fields);
    /**
     * 按HQL分页查询.
     *
     * @param page   分页参数.不支持其中的orderBy参数.
     * @param hql    hql语句.
     * @param values 数量可变的查询参数,按顺序绑定.
     * @return 分页查询结果, 附带结果列表及所有查询时的参数.
     */
    @SuppressWarnings("unchecked")
    public Page findPage(final Page page, final String hql, final Object... values);

    /**
     * 按HQL分页查询.
     *
     * @param page   分页参数.(不支持orderBy参数)
     * @param hql    hql语句.
     * @param values 命名参数,按名称绑定.
     * @return 分页查询结果, 附带结果列表及所有查询时的参数.
     */
    @SuppressWarnings("unchecked")
    public Page findPage(final Page page, final String hql, final Map<String, Object> values);
    /**
     * 按属性过滤条件列表分页查找对象.
     */

    public Page findPage(final Class clazz,final Page page, final List<PropertyFilter> filters);
    
    /**
     * HQL分页查询所有数据
     */
    
    public Page getAll(final Class clazz,final Page page);
}
